package cn.ybk.org.service.impl;

import cn.ybk.basic.query.BaseQuery;
import cn.ybk.basic.service.impl.BaseServiceImpl;
import cn.ybk.basic.util.BaiduAuditUtils;
import cn.ybk.basic.util.BusinessException;
import cn.ybk.basic.util.EmailUtil;
import cn.ybk.basic.util.PageList;
import cn.ybk.org.domain.Employee;
import cn.ybk.org.domain.Shop;
import cn.ybk.org.domain.ShopAuditLog;
import cn.ybk.org.dto.ShopAdminDto;
import cn.ybk.org.dto.ShopAuditDto;
import cn.ybk.org.dto.ShopResultDto;
import cn.ybk.org.dto.ShopSettlementDto;
import cn.ybk.org.mapper.EmployeeMapper;
import cn.ybk.org.mapper.ShopAuditLogMapper;
import cn.ybk.org.mapper.ShopMapper;
import cn.ybk.org.service.EmployeeService;
import cn.ybk.org.service.IShopService;
import cn.ybk.user.domain.Logininfo;
import cn.ybk.user.mapper.LogininfoMapper;
import com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ShopServiceImpl extends BaseServiceImpl<Shop> implements IShopService {

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private ShopAuditLogMapper shopAuditLogMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;


    // 抽取代码 ctrl + alt + m
    // 一部分代码为判断数据
    // 一部分代码为添加数据库

    // 下拉三角
    @Override
    public PageList<Shop> queryByPage(BaseQuery query) {
        // 父级为：shop的id
        // 套路：
        // 先获取到父级的集合
        // 根据父级的id集合查询出来所有的子级集合
        // 将子级集合根据父级的id进行分组 转成map
        // 遍历父级集合 使用map.get(父级的id)
        // 将子级放入到父级

        // 获取shop表中的全部数据
        PageList<Shop> shopPageList = super.queryByPage(query);

        // 所以需要获取里面的rows --> 即数据库的数据全部获取到了
        List<Shop> rows = shopPageList.getRows();
        // 查询所有店铺的id 并且转换为list集合
        List<Long> shopId = rows.stream().map(Shop::getId).collect(Collectors.toList());
        // 根据店铺id去查询审核表中的ShopId
        List<ShopAuditLog> byLog = shopAuditLogMapper.findByLog(shopId);
        // 根据shop表中的id进行分组
        Map<Long, List<ShopAuditLog>> collect = byLog.stream().collect(Collectors.groupingBy(ShopAuditLog::getShopId));
        rows.forEach(shop -> {
            List<ShopAuditLog> logs = collect.get(shop.getId());
            shop.setAuditLogs(logs);

        });
        return shopPageList;

    }

    // 商家入驻
    @Override
    public void settlement(ShopSettlementDto dto) {
        // 数据校验
        judge(dto);
        // 添加数据库
        save(dto);

    }

    // 审核通过
    @Override
    public void auditPass(ShopAuditDto dto) {
        // 三件事
        // 1.修改状态为待激活！！
        Shop shop = new Shop();
        shop.setState(1);
        shop.setId(dto.getShopId());
        shopMapper.update(shop);
        // 2.发送邮件给用户！！
        // 获取邮箱
        Employee byId = employeeMapper.findByShopId(dto.getShopId());
        String email = byId.getEmail();
        // 抽取成工具类
        //    EmailUtil.sendEmail("XXXXXX(收件人邮箱)@qq.com",
        //    "XXXXXX(发件人邮箱)@qq.com",
        //    "(授权邮箱，一般就是填发件人邮箱)XXXXX@qq.com",
        //    "发件人的QQ邮箱里的授权码",
        //    "邮件名",
        //    "邮件内容");
        EmailUtil.sendEmail(email,
                "3533670493@qq.com",
                "3533670493@qq.com",
                "cyuekqvrgrxxdbif",
                "宠物乐园有限公司提示你：",
                "<h1>恭喜你，通过店铺入驻，现在只需要点击下面的网站，即可完成激活哟~</h1>" +
                        "http://localhost:8080/shop/activity/" + dto.getShopId());

        // 3.添加审核日志！！
        ShopAuditLog shopAuditLog = new ShopAuditLog();
        shopAuditLog.setShopId(dto.getShopId());
        shopAuditLog.setAuditId(-1);
        shopAuditLog.setNote(dto.getNote());
        shopAuditLog.setAuditTime(new Date());
        shopAuditLogMapper.add(shopAuditLog);
    }

    // 激活店铺
    @Override
    public void activity(Long id) {
        Shop shop = new Shop();
        shop.setState(2);
        shop.setId(id);
        shopMapper.update(shop);
    }

    // 驳回
    @Override
    public void auditReject(ShopAuditDto dto) {
        // 驳回 修改状态
        Shop shop = new Shop();
        shop.setState(3);
        shop.setId(dto.getShopId());
        shopMapper.update(shop);
        // 发送邮件 内含重新修改的页面  http://localhost:8080/shop/activity/ 改成路由地址
        Employee byId = employeeMapper.findByShopId(dto.getShopId());
        String email = byId.getEmail();
        EmailUtil.sendEmail(email,
                "3533670493@qq.com",
                "3533670493@qq.com",
                "cyuekqvrgrxxdbif",
                "宠物乐园有限公司提示你：",
                "<h1>很抱歉，你填的信息有误，请重新修改</h1>" +
                        "http://localhost:8081/#/registerAgain/" + dto.getShopId());
        // 添加日志
        ShopAuditLog shopAuditLog = new ShopAuditLog();
        shopAuditLog.setShopId(dto.getShopId());
        shopAuditLog.setAuditId(-1);
        shopAuditLog.setNote(dto.getNote());
        shopAuditLog.setAuditTime(new Date());
        shopAuditLogMapper.add(shopAuditLog);
    }

    // 驳回之后重新发送入驻信息
    @Override
    public void settlementAgain(ShopResultDto dto) {
        Boolean booName = BaiduAuditUtils.TextCensor(dto.getName());
        Boolean booLogo = BaiduAuditUtils.ImgCensor(dto.getLogo());
        if (!booName) {
            throw new BusinessException("别乱起名字哟~");
        }
        if (!booLogo) {
            throw new BusinessException("过于暴露啦~");
        }
        Shop shop = new Shop();
        shop.setId(dto.getId());
        shop.setName(dto.getName());
        shop.setState(0);
        shop.setTel(dto.getTel());
        shop.setLogo(dto.getLogo());

        shopMapper.update(shop);

    }

    @Override
    public ShopAuditLog drawer(Long id) {
        return shopMapper.drawer(id);
    }


    private void judge(ShopSettlementDto dto) {
        // 1.校验数据非空，格式
        // @NotBlank(message = "用户名不能为空！")
        ShopAdminDto admin = dto.getAdmin();
        // 2.两次输入密码是否一致
        String password = admin.getPassword();
        String comfirmPassword = admin.getComfirmPassword();
        if (!password.equals(comfirmPassword)) {
            throw new BusinessException("两次密码不一致");
        }
        // 3.判断店铺是否被注册
        // 查询数据库名字
        String name = dto.getName();
        Shop byName = shopMapper.findByName(name);
        // 如果名字存在，即被注册了
        // 如果不存在，即没被祖册
        if (byName != null) {
            throw new BusinessException("店铺名已经被注册");
        }
        // 4.判断管理员是否管理了店铺
        // 查询数据库中emp表中的username
        String username = admin.getUsername();
        Employee employee = employeeMapper.findByName(username);
        // 如果emp表中有这个名字，且他的shopId不等于空，那就说明。这个username是该店铺的人
        // 但是不确定是不是店长
        if (employee != null && employee.getShopId() != null) {
            // 现在就需要获取shop表中的adminId
            Long id = employee.getId();
            Shop byAdminId = shopMapper.findByAdminId(id);
            if (byAdminId != null) {
                throw new BusinessException("换个人吧这个人已经有官了");
            }
        }
        // 5. 百度ai
        Boolean booName = BaiduAuditUtils.TextCensor(dto.getName());
        Boolean booLogo = BaiduAuditUtils.ImgCensor(dto.getLogo());

        if (!booName) {
            throw new BusinessException("你再乱起名字，我头给你拧下来");
        }
        if (!booLogo) {
            throw new BusinessException("照片我很喜欢，但是不能上传哟~");
        }
    }

    private void save(ShopSettlementDto dto) {
        // 6.存入数据库
        // 先将存入shop表的数据  然后存入emp表的数据，最后shop表更新数据
        // 获取shop对象
        Shop shop = dto.getShop();
        // 调用添加方法
        shopMapper.add(shop);
        // 获取emp对象
        Employee emp = dto.getEmp();
        // 在employeeService中执行了添加logininfo方法
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(emp, logininfo);
        logininfo.setType(0);
        logininfo.setDisable(true);
        logininfoMapper.add(logininfo);
//        // 先执行了 shopMapper.add(shop) 方法，然后shop中就有id值了
//        // 现在直接set 设置id值给emp表中的shopId
        emp.setShopId(shop.getId());
        emp.setLogininfoId(logininfo.getId());
        ArrayList<Long> roles = new ArrayList<>();
        roles.add(20L);
        employeeMapper.addToEmpRole(emp.getId(),roles);
        // 执行添加方法
        employeeMapper.add(emp);
        // 所有方法执行完毕之后，更新shop表中的adminId
        // 创建一个空shop对象
        Shop shop1 = new Shop();
        // 重新设置Id
        shop1.setId(shop.getId());
        // 获取emp表中的Id 赋值给shop表中的adminId
        shop1.setAdminId(emp.getId());
        shopMapper.update(shop1);
    }

}
